#ifndef __AnimatedEntity_H_
#define __AnimatedEntity_H_

#include <string>
#include <iostream>

#include "Entity.h"


/*!
	The AnimatedEntity class provides the bases for read and animate a mesh for an Entity. You can optionnaly load a weapon.
	Notes about meshes and IAnimatedMesh (and other mesh classes):
	The meshes are never freed or dropped or removed from the 3D engine's mesh cache. Doing this may corrupt other existing instances of these meshes. The Irrlicht documentation does not show any example of doing things properly, so I decided not to free them for now.
*/
class AnimatedEntity: virtual public Entity
{
	protected:
	std::pair<s32, s32> animFrames__;	/**< A pair containing the first and last frames for the current animation. Should not be used in cunjuction with animString__ and animType__. */
	irr::core::string<c8> animString__;	/**< A string containing the name of current animation. Should not be used in cunjuction with animFrames__ and animType__. */
	EMD2_ANIMATION_TYPE animType__;		/**< A value from an irrlicht's enumaration containing the current animation. Should not be used in cunjuction with animFrames__ and animString__. */

	IAnimatedMesh* entityMesh__;		/**< The mesh of the Entity. */

	IAnimatedMesh* weaponMesh__;		/**< The mesh of the weapon. */
	IAnimatedMeshSceneNode* weaponNode__;	/**< The node of the weamon. */

	/*! Removes the weapon's node from the scene graph (if needed), and sets the mesh to 0. */
	void clearWeapon();

	public:
	/*! Constructor. It initializes the mesh with the given path to model and skin; and optionnaly initializes the weapon with the given path to model and skin. The program should crash if the model path is wrong (unless it is "" for weaponModel only). */
	AnimatedEntity(const irr::core::string<c8>& entityModel, const irr::core::string<c8>& entitySkin, const irr::core::string<c8>& weaponModel="", const irr::core::string<c8>& weaponSkin="");
	/*! Destructor. Initializes entitiMesh__ to 0 without cleaning it from memory (which is the awaited behaviour for now), and then cleans the weapon's node (if needed). The Entity's node is dropped in the Entity's destructor. */
	virtual ~AnimatedEntity();

	/*! Sets the animation frames from frames.first to frames.second, the loop argument is yet to test. */
	void setAnimation(std::pair<s32, s32> frames, bool loop=true);
	/*! Sets the animation frames from start to end, the loop argument is yet to test. */
	void setAnimation(s32 start, s32 end, bool loop=true);
	/*! Sets the animation frames to the corresponding string. Return true if successfull. Successfull means that the animation state could be set for the Entity AND the weapon (if there is a weapon). */
	bool setAnimation(const irr::core::string<c8>& animName, bool loop=true);
	/*! Sets the animation frames to the corresponding value. Return true if successfull. Successfull means that the animation stage could be set for the Entity AND the weapon (if there is a weapon). */
	bool setAnimation(EMD2_ANIMATION_TYPE animName, bool loop=true);

	/*! Clears the exasting weapon if needed, then loads the weapon using the given model and skin. Should crash if the path to weapon's model is wrong. */
	void setWeapon(const irr::core::string<c8>& weaponModel, const irr::core::string<c8>& weaponSkin);

	/*! TODO: this method should hide the weapon without clearing it. */
	void hideWeapon() {}
	/*! TODO: this method should show the weapon. */
	void showWeapon() {}
	/*! TODO: this method should toggle the weapon's visibility without clearing it. */
	void toggleWeapon() {}

	/*! Redefines Entity::getNode() to return an IAnimatedMeshSceneNode* instead of an ISceneNode* */
	virtual IAnimatedMeshSceneNode* getNode();

	/*! returns the node associated to the mesh (not to the weapon) */ 
	virtual IAnimatedMeshSceneNode * getMeshNode() ;

	/*! This method just returns the mesh, I don't remember the purpose of it. */
	IAnimatedMesh* getEntityMesh();
};

#endif

